﻿using ACC.Data.Entities.Common;
using ACC.Data.Entities.Mes;
using ACC.Extensions.ClientBusiness;
using ACC.Extensions.ClientBusiness.PLC;
using ACC.Extensions.Entities;
using ACC.Extensions.PCClient.BaseWindow;
using ACC.Extensions.PCClient.Helper;
using ACC.Extensions.PCClient.UserControls;
using ACC.Extensions.Utilities;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ACC.Extensions.PCClient.Entities;
using ACC.Data.Entities.Common;

namespace ACC.Extensions.PCClient.View
{
    /// <summary>
    /// MainWnd.xaml 的交互逻辑
    /// </summary>
    public partial class MainWnd : BaseCustomWindow_New
    {
        //串口扫描枪
        private ComScanner comScanner = null;

        //基本信息对象
        public ClientBasicInfo CurrentBasicInfo;

        //设备列表
        private List<DeviceStatus> lstDeviceStatus;

        private object _lockObj = new object();

        //记录扫描的条码
        //private string _scanBarcode = "";

        private bool _isRun = false;

        //记录选择件的加工结果，默认结果OK
        //0: NG ; 1: OK; 2:Repair
        int unloadResult = 1;
        UnloadVariable unloadNGData = null;

        /*
         * 判断是否需要手动输入OKNOK，如果需要的话，就不需要从PLC读取结果，不需要PLC来发Unload信号
         * Add By Han 2020-11-30
         */
        private bool IsManualResult
        {
            get { return UISession.ClientSetting.IsNOKBtn || UISession.ClientSetting.IsOKBtn; }
        }

        //需要额外显示的组件名称
        string[] ShowComponnets;

        public MainWnd()
        {
            InitializeComponent();
            //从配置文件读取端口
            inAccPort = AppConfigHelper.GetAppSettings("SocketPort").ToInt();
            debugMode = AppConfigHelper.GetAppSettings("DebugMode").ToString();

            ShowComponnets = string.IsNullOrEmpty(AppConfigHelper.GetAppSettings("ShowComponent")) ? null : AppConfigHelper.GetAppSettings("ShowComponent").Split(';');

        }

        /// <summary>
        /// 窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BaseCustomWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //禁用所有控件
            DisableUIControls();
            //初始化设备列表
            InitDeviceStatus();
            //初始化基本信息
            InitBasicInfo();
            //初始化当前日志
            InitLog();
            //创建AccProcess对象
            CreateAccProcess();
            //创建Socketserver监听ACC和PLC的连接
            CreateAccSocketServer();

            if (UISession.ClientSetting.COM_Enable)
            {
                comScanner = new ComScanner();
                comScanner.Init(UISession.ClientSetting.COM_PortName,
                    UISession.ClientSetting.COM_BaudRate,
                    UISession.ClientSetting.COM_Parity,
                    UISession.ClientSetting.COM_DataBits,
                    UISession.ClientSetting.COM_StopBits);
                comScanner.OnBCRead += comScanner_OnBCRead;
                comScanner.OnBCStatusChanged += comScanner_OnBCStatusChanged;
            }

            //去掉窗体顶部栏
            this.UseNoneWindowStyle = true;
            //忽略任务栏最大化
            this.IgnoreTaskbarOnMaximize = true;
            //窗体初始最大化
            this.WindowState = WindowState.Maximized;

            //SetBarcodeHandle();

            //加载操作手册
            //LoadHelp();
        }

        /// <summary>
        /// 窗体激活
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BaseCustomWindow_Activated(object sender, EventArgs e)
        {
            UISession.IsWndActivated = this.IsActive;
        }

        /// <summary>
        /// 窗体未激活
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BaseCustomWindow_Deactivated(object sender, EventArgs e)
        {
            UISession.IsWndActivated = this.IsActive;
        }

        private List<string> LoadDataGridBarcode()
        {
            List<string> barcodes = new List<string>();
            try
            {
                DataTable dt = clientSqlLite.GetBarcode("OK");
                foreach (DataRow row in dt.Rows)
                {
                    barcodes.Add(row["Barcode"].ToString());
                }
            }
            catch { }
            return barcodes;
        }

        #region 界面初始化

        /// <summary>
        /// 初始化基本信息
        /// </summary>
        private void InitBasicInfo()
        {
            CurrentBasicInfo = new ClientBasicInfo() { };
            CurrentBasicInfo.ShowOKCount = true;//显示OK计数
            dgBasicinfo.Content = CurrentBasicInfo;
        }

        /// <summary>
        /// 初始化设备状态列表
        /// </summary>
        private void InitDeviceStatus()
        {
            lstDeviceStatus = new List<DeviceStatus>();

            DeviceStatus device;
            //PLC
            if (UISession.ClientSetting.EnablePLC)
            {
                device = new DeviceStatus();
                device.Name = UISession.ClientSetting.PLCDescription;
                lstDeviceStatus.Add(device);
            }

            //串口扫码枪
            if (UISession.ClientSetting.COM_Enable)
            {
                device = new DeviceStatus();
                device.Name = LanguageHelper.LoadStringFromResource("SCANNER");
                lstDeviceStatus.Add(device);
            }

            //ACC
            device = new DeviceStatus();
            device.Name = LanguageHelper.LoadStringFromResource("LABEL_ACC_STATUS");
            lstDeviceStatus.Add(device);
            lstDevice.ItemsSource = lstDeviceStatus;
        }

        /// <summary>
        /// 初始化日志
        /// </summary>
        private void InitLog()
        {
            lstLogs = new ObservableCollection<HistoryLog>();
            lvHistoryLog.ItemsSource = lstLogs;
        }

        /// <summary>
        /// 初始化条码列表
        /// </summary>
        private void InitBarcodes()
        {
            Dispatcher.Invoke(new Action(() =>
                {
                    dgBarcode.Init();
                }));

        }
        #endregion

        #region 界面元素设置

        /// <summary>
        /// 完成Load/Unload周期后，重置一些界面字段
        /// </summary>
        private void ResetCycle()
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.btnOK.IsEnabled = false;
                this.btnNG.IsEnabled = false;
                this.btnRepair.IsEnabled = false;
            }));

            clientSqlLite.DeleteBarcodeAll();
            dgBarcode.ClearAllBarcodes();
            ResetUnloadDec();
        }

        /// <summary>
        /// 根据一些条件判断控件Enable或Disable
        /// </summary>
        private void RefreshElementState()
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (!accSocketServer.GetAccSocketStatus() || UISession.CurrentPartType == null)
                {
                    DisableUIControls();
                }
                else
                {
                    EnableUIControls();
                    //控制登陆相关的两个按钮
                    if (UISession.ClientSetting.UseLineLeaderAssign)
                    {
                        //线长指派工位，Login按钮不可用
                        this.btnLogin.IsEnabled = false;
                    }

                    //如果时需要登陆的，则判断是否已经登陆
                    if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
                    {
                        //这时候扫描框是不能操作的
                        DisableUIControls();
                        this.btnLogin.IsEnabled = true;
                    }
                }
            }));
        }

        /// <summary>
        /// 禁用控件
        /// </summary>
        private void DisableUIControls()
        {
            this.txtScan.IsEnabled = false;
            this.btnLogin.IsEnabled = false;
            this.btnReset.IsEnabled = false;
            this.btnOK.IsEnabled = false;
            this.btnNG.IsEnabled = false;
            this.btnRepair.IsEnabled = false;
        }

        //启用主界面所有控件
        private void EnableUIControls()
        {
            this.btnLogin.IsEnabled = true;
            this.btnReset.IsEnabled = true;
        }

        /// <summary>
        /// 更新设备连接状态
        /// </summary>
        /// <param name="strDeviceName"></param>
        /// <param name="bIsConnected"></param>
        public override void UpdateDeviceStatus(string strDeviceName, bool bIsConnected)
        {
            var device = lstDeviceStatus.Find(x => x.Name.Equals(strDeviceName));
            if (device != null)
            {
                device.IsConnected = bIsConnected;
            }
        }

        /// <summary>
        /// 设置扫码框状态
        /// 根据托盘的信号来判断是否可以扫描，有PLC的站点 comment by Han 2020-11-28
        /// </summary>
        /// <param name="isenable"></param>
        public void SetScanEnable(bool isenable)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                if (plcProcess != null)
                {
                    if (PalletStatus && isenable)
                    {
                        this.txtScan.IsEnabled = true;
                    }
                    else
                    {
                        this.txtScan.IsEnabled = false;
                    }
                }
                else
                {
                    this.txtScan.IsEnabled = isenable;
                }


            }));
        }

        #endregion

        #region 串口扫码枪

        /// <summary>
        /// 读码
        /// </summary>
        /// <param name="bc"></param>
        private void comScanner_OnBCRead(string bc)
        {
            //显示扫描信息
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.txtScan.Text = bc;

                HandleBarcode(bc);
            }));
        }

        /// <summary>
        /// 更新连接状态
        /// </summary>
        /// <param name="connect"></param>
        private void comScanner_OnBCStatusChanged(bool connect)
        {
            UpdateDeviceStatus(LanguageHelper.LoadStringFromResource("SCANNER"), connect);
        }
        #endregion

        #region 菜单栏操作
        private void MenuItem_MouseEnter(object sender, MouseEventArgs e)
        {
            ChangeIcon();
        }

        private void MenuItem_MouseLeave(object sender, MouseEventArgs e)
        {
            ChangeIcon();
        }

        /// <summary>
        /// 修改Icon的图标
        /// </summary>
        private void ChangeIcon()
        {
            string imgName = MiConfig.IsHighlighted ? "配置2.png" : "配置.png";
            ((Image)MiConfig.Icon).Source = new BitmapImage(new System.Uri(@"pack://application:,,,/Resources/Custom/Image/" + imgName));

            imgName = MiLang.IsHighlighted ? "语言2.png" : "语言.png";
            ((Image)MiLang.Icon).Source = new BitmapImage(new System.Uri(@"pack://application:,,,/Resources/Custom/Image/" + imgName));

            imgName = MiHelp.IsHighlighted ? "帮助2.png" : "帮助.png";
            ((Image)MiHelp.Icon).Source = new BitmapImage(new System.Uri(@"pack://application:,,,/Resources/Custom/Image/" + imgName));
        }

        /// <summary>
        /// 本地配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miClientConfig_Click(object sender, RoutedEventArgs e)
        {
            UserValidateWnd dialogWnd = new UserValidateWnd();
            var dialogResult = dialogWnd.ShowDialog();
            if (!(dialogResult.HasValue && dialogResult.Value))
            {
                return;
            }
            ConfigClientWnd configWnd = new ConfigClientWnd();
            configWnd.ShowDialog();
        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            if (accSocketServer != null)
            {
                accSocketServer.AccSocketStop();
            }

            CloseClientPLC();

            if (UISession.ClientSetting.COM_Enable && comScanner != null)
            {
                comScanner.Uninit();
            }

            Application.Current.Shutdown();

            //this.Close();
        }

        /// <summary>
        /// 语言切换成中文
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miChinese_Click(object sender, RoutedEventArgs e)
        {
            LanguageHelper.SelectChinese();
            //保存语言配置
            AppConfigHelper.UpdateAppSettings("Lang", "cn");
        }

        /// <summary>
        /// 语言切换成英文
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miEnglish_Click(object sender, RoutedEventArgs e)
        {
            LanguageHelper.SelectEnglish();
            //保存语言配置
            AppConfigHelper.UpdateAppSettings("Lang", "en");
        }

        /// <summary>
        /// 关于
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void miAbout_Click(object sender, RoutedEventArgs e)
        {
            AboutWnd aboutWnd = new AboutWnd();
            aboutWnd.ShowDialog();
        }

        #endregion

        #region 界面切换按钮

        /// <summary>
        /// 主操作界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMain_Click(object sender, RoutedEventArgs e)
        {
            SetButtonClicked(btnMain);
            ChangeTab(gdMain);

        }

        /// <summary>
        /// 操作指导
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSop_Click(object sender, RoutedEventArgs e)
        {
            SetButtonClicked(btnSop);
            ChangeTab(gdSop);

            //string SopFolderFullName = System.AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["SopFolder"].ToString();
            //LoadLocalFiles(null, SopFolderFullName);
        }

        /// <summary>
        /// 售后质量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnIssue_Click(object sender, RoutedEventArgs e)
        {
            SetButtonClicked(btnIssue);
            ChangeTab(gdIssue);

        }

        /// <summary>
        /// 日志历史
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnHistory_Click(object sender, RoutedEventArgs e)
        {
            SetButtonClicked(btnHistory);
            ChangeTab(gdHistoryLog);
        }

        private void btnSetting_Click(object sender, RoutedEventArgs e)
        {
            SetButtonClicked(btnSetting);
            ChangeTab(gdSetting);
        }

        /// <summary>
        /// 设置按钮点击后外观为选中状态
        /// </summary>
        /// <param name="btn"></param>
        private void SetButtonClicked(ImageButton btn)
        {
            btnMain.IsClicked = false;
            btnSop.IsClicked = false;
            btnIssue.IsClicked = false;
            btnHistory.IsClicked = false;
            btnSetting.IsClicked = false;
            btn.IsClicked = true;
        }

        /// <summary>
        /// 切换主页面内容
        /// </summary>
        /// <param name="dgShow"></param>
        private void ChangeTab(Grid dgShow)
        {
            gdMain.Visibility = Visibility.Hidden;
            gdHistoryLog.Visibility = Visibility.Hidden;
            gdSetting.Visibility = Visibility.Hidden;
            gdSop.Visibility = Visibility.Hidden;
            gdIssue.Visibility = Visibility.Hidden;

            dgShow.Visibility = Visibility.Visible;

//            //关闭/开启 正在播放的SOP
//            if (gdSop.Visibility == Visibility.Visible)
//            {
//                if (sopMediaPlayer.status == "已暂停")
//                    sopMediaPlayer.Ctlcontrols.play();
//            }
//            else
//            {
//                sopMediaPlayer.Ctlcontrols.pause();
//            }
        }

        #endregion

        #region 主操作按钮

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            //for test
//            if (plcProcess != null)
//            {
//                List<ClientProcData> lstProcessData = UISession.CurrentPartTypeData != null ? UISession.CurrentPartTypeData.ProcDatas.ToList() : null;
//                plcProcess.GetProcData(ref lstProcessData);
//            }
            UserLoginWnd userLoginWnd = new UserLoginWnd();
            var dialogResult = userLoginWnd.ShowDialog();

            string operatorId = string.Empty;
            if (!dialogResult.HasValue || !dialogResult.Value)
            {
                return;
            }
            operatorId = userLoginWnd.OperatorId;

            string msg = String.Empty;
            UISession.CurrentOperator = accProcess.OperatorLogin(operatorId, out msg);
            if (!String.IsNullOrEmpty(msg))
            {
                MessageDialogWnd.ShowDialog("Error", msg);
            }
            else
            {
                CurrentBasicInfo.StnOperator = String.Format("{0}({1})", UISession.CurrentOperator.Name, UISession.CurrentOperator.OperatorId);
                RefreshElementState();
                SetScanEnable(true);
            }
        }


        /// <summary>
        /// 点击合格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
            {
                btnLogin_Click(null, null);
            }
            else
            {
                //带PLC工位的，点击在Unload请求之前，记录结果
                unloadResult = 1;
                AddLog("操作员判定生产结果:OK", false);


                bool result = ProcessUnload(1);
                //非PLC工位，直接Unload
                if (plcProcess != null)
                {
                    if (result)
                    {
                        plcProcess.UnloadSuccessfully(1);
                    }
                    else
                    {
                        plcProcess.UnloadFailed();
                    }
                }
               
            }
        }

        /// <summary>
        /// 点击不合格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNG_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
            {
                btnLogin_Click(null, null);
            }
            else
            {
                string barcode = dgBarcode.MainItem != null ? dgBarcode.MainItem.IDValue : string.Empty;
                ResultWithReasonWnd Wnd = new ResultWithReasonWnd(barcode, false, GetStatusBitList(UISession.CurrentPartType));
                var dialogResult = Wnd.ShowDialog();
                if (dialogResult.HasValue && dialogResult.Value)
                {
                    //带PLC工位的，点击在Unload请求之前，记录结果
                    unloadResult = 0;
                    unloadNGData = Wnd.UnloadData;

                    AddLog("操作员判定生产结果:NG", false);

                    bool result = ProcessUnload(0, Wnd.UnloadData);
                    //非PLC工位，直接Unload
                    if (plcProcess != null)
                    {
                        if (result)
                        {
                            plcProcess.UnloadSuccessfully(1);
                        }
                        else
                        {
                            plcProcess.UnloadFailed();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 点击在线返修
        /// 只配给PLC工位,需要返修的标记写回PLC
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRepair_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.ClientSetting.NeedOperatorLogin && UISession.CurrentOperator == null)
            {
                btnLogin_Click(null, null);
            }
            else
            {
                ResultWithReasonWnd Wnd = new ResultWithReasonWnd(dgBarcode.MainItem.IDValue, false, GetStatusBitList(UISession.CurrentPartType));
                var dialogResult = Wnd.ShowDialog();
                if (dialogResult.HasValue && dialogResult.Value)
                {
                    unloadResult = 2;
                    unloadNGData = Wnd.UnloadData;
                }
            }
        }

        /// <summary>
        /// 获取StatusBits
        /// </summary>
        /// <param name="partType"></param>
        /// <returns></returns>
        private List<DefectData> GetStatusBitList(ClientPartType partType)
        {
            if (partType == null)
            {
                return new List<DefectData>();
            }
            //AutoChangModelbyPartType(partType, this.lvMessage);
            List<DefectData> lstDefectData = new List<DefectData>();
            List<ClientFailureWord> lstStatusWord = UISession.CurrentPartTypeData != null && UISession.CurrentPartTypeData.StatusBits.Count > 0 ? UISession.CurrentPartTypeData.StatusBits : new List<ClientFailureWord>();
            for (int i = 0; i < lstStatusWord.Count; i++)
            {
                if (lstStatusWord[i].StatusBits != null)
                {
                    foreach (ClientFailureBit item in lstStatusWord[i].StatusBits)
                    {
                        DefectData defectData = new DefectData();
                        defectData.StatusName = lstStatusWord[i].Name;
                        defectData.IsChecked = false;
                        defectData.InBit = item.Bit;
                        if (item.Description.IndexOf(':') > -1)
                        {
                            defectData.DefectCode = item.Description.Substring(0, item.Description.IndexOf(':') == -1 ? 0 : item.Description.IndexOf(':'));
                            defectData.DefectDescription = item.Description.Substring(item.Description.IndexOf(':') + 1, item.Description.Length - item.Description.IndexOf(':') - 1);
                            lstDefectData.Add(defectData);
                        }
                    }
                }
            }
            return lstDefectData;
        }

        /// <summary>
        /// 设置3个Button的状态
        /// </summary>
        /// <param name="enable"></param>
        private void SetDecideBtn(bool enable)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.btnOK.IsEnabled = enable ? UISession.ClientSetting.IsOKBtn : enable;
                this.btnNG.IsEnabled = enable ? UISession.ClientSetting.IsNOKBtn : enable;
                this.btnRepair.IsEnabled = enable ? UISession.ClientSetting.IsRepairBtn : enable;
            }));
        }

        /// <summary>
        /// 点击报警复位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReset_Click(object sender, RoutedEventArgs e)
        {

            //Dispatcher.Invoke(new Action(() =>
            //    {
            AddLog("操作员选择报警复位", false);
            dgBarcode.ClearAllBarcodes();
            CurrentBasicInfo.PalletNo = "";
            //  }));
        }

        /// <summary>
        /// 点击打印
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPrint_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(CurrentBasicInfo.PalletNo))
            {
                ClientResponse result = accProcess.Print(CurrentBasicInfo.PalletNo);
                if (result.Result)//打印成功
                {
                    AddLog(LanguageHelper.LoadStringFromResource("MSG_PRINT_SUCCESS"), false);
                }
                else//打印失败
                {
                    AddLog(LanguageHelper.LoadStringFromResource("MSG_ERR_PRINT") + "：" + result.Message, true);
                }
            }
        }

        #endregion

        #region ACC通讯

        #region ACC连接
        /// <summary>
        /// ACC连接事件
        /// </summary>
        public override void AccSocketServerConnected()
        {
            Console.WriteLine("AccSocketServerConnected");
            UpdateDeviceStatus(LanguageHelper.LoadStringFromResource("LABEL_ACC_STATUS"), true);

            AddLog(LanguageHelper.LoadStringFromResource("MSG_CONNECTED_ACC"), false);

            //连接PLC
            ConnectClientPLC();

            RefreshElementState();
        }

        /// <summary>
        /// 响应ACC连接，更新界面元素
        /// </summary>
        public override void AccSocketServerConfigChanged()
        {
            if (UISession.CurrentClient == null)
            {
                return;
            }

            AddLog(String.Format(LanguageHelper.LoadStringFromResource("MSG_GET_CLIENT_CONFIG"),
                UISession.CurrentClient.ServerIP, UISession.CurrentClient.ServerPort), false);
            try
            {
                //获取到配置后，连接ACC
                if (!bIsAccConnected)
                {
                    bIsAccConnected = accProcess.Connect(UISession.CurrentClient);
                }

                if (bIsAccConnected)
                {
                    string msg = String.Empty;
                    //获取PartTypeList
                    UISession.PartTypeList = accProcess.GetPartTypeList(out msg);
                    if (!String.IsNullOrEmpty(msg))
                    {
                        AddLog(String.Format("Get part type list occurred error: {0}", msg), true);
                    }
                    else
                    {
                        AddLog(LanguageHelper.LoadStringFromResource("MSG_GET_PARTTYPE_LIST_OK"), false);
                        if (UISession.CurrentClient.PartTypeId > 0)
                        {
                            Thread.Sleep(1000);
                            var partType = UISession.PartTypeList.FirstOrDefault<ClientPartType>(p => p.PartTypeId == UISession.CurrentClient.PartTypeId);
                            //换型完成后，填充界面信息
                            CurrentBasicInfo.PartNo = partType.PartNo;
                            CurrentBasicInfo.PartNoDesc = partType.Description;
                            AccSocketServerChangeover(partType);
                        }
                    }

                    //当接收到操作工信息后，填充当前登陆的操作工信息
                    if (!String.IsNullOrEmpty(UISession.CurrentClient.Name)
                        && !String.IsNullOrEmpty(UISession.CurrentClient.OperatorId))
                    {
                        UISession.CurrentOperator = new ClientOperator
                        {
                            OperatorId = UISession.CurrentClient.OperatorId,
                            Name = UISession.CurrentClient.Name
                        };

                        CurrentBasicInfo.StnOperator = UISession.CurrentOperator.ShowValue;
                        SetScanEnable(true);
                    }

                    // 用ACC Server时间同步系统时间
                    DateTime dt = accProcess.GetDateTime();
                    if (dt != DateTime.MinValue && dt != DateTime.MaxValue)
                    {
                        dt.AddSeconds(0.2);
                        SysDateTime.SetDate(dt);
                    }
                }
                //填充界面              
                CurrentBasicInfo.StnName = UISession.CurrentClient.STN;
                CurrentBasicInfo.StnDesc = UISession.CurrentClient.Description;
                ClientShiftCfg shift = UISession.CurrentClient == null || UISession.CurrentClient.ShiftCfg == null ? null : UISession.CurrentClient.ShiftCfg;
                CurrentBasicInfo.Shift = string.Format("{0}({1})", shift.ShiftName, shift.ShiftOrder);

                //所有获取配置的事情做完后，设置一下界面控件
                RefreshElementState();

                //初始化配置
                InitSettings();
            }
            catch (Exception ex)
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    MessageDialogWnd.ShowDialog("", "ClientSocket_OnClientConfigChanged Error:" + ex.Message);
                }));
                Log4Helper.Error("ClientSocket_OnClientConfigChanged Error: ", ex);
            }
        }

        /// <summary>
        /// ACC断开连接
        /// </summary>
        public override void AccSocketServerDisconnected()
        {
            try
            {
                CloseClientPLC();
                //  ClosePcClientThread();
                UpdateDeviceStatus(LanguageHelper.LoadStringFromResource("LABEL_ACC_STATUS"), false);

                //Step1
                AddLog(LanguageHelper.LoadStringFromResource("MSG_DISCONNECTED_ACC"), true);

                //断连后需要将UISession中所有的缓存信息都清除，恢复到初始状态
                UISession.CurrentClient = null;
                UISession.CurrentPartType = null;
                UISession.CurrentOperator = null;
                UISession.CurrentPartTypeData = null;

                //清空基础信息
                CurrentBasicInfo.Clear();
                //清空条码列表
                InitBarcodes();

                bIsAccConnected = false;
                RefreshElementState();
            }
            catch (Exception ex)
            {
                Log4Helper.Error(ex.StackTrace);
            }
        }

        #endregion

        #region 换型
        /// <summary>
        /// 响应ACC换型
        /// </summary>
        public override void AccSocketServerChangeover(ClientPartType partType)
        {
            //不重复换型判断
            if (UISession.CurrentPartType != null && UISession.CurrentPartType.PartTypeId == partType.PartTypeId)
            {
                // 更新物料信息
                if (UISession.CurrentPartTypeData != null && UISession.CurrentPartTypeData.ComponentSet != null)
                {
                    FillLotTrack(UISession.CurrentPartTypeData.ComponentSet);
                }
                else
                {
                    FillLotTrack(new List<ClientLotTrackItem>());
                }
                return;
            }
            if (partType == null)
            {
                return;
            }

            try
            {
                lock (_lockObj)
                {
                    if (partType.PartTypeId > 0)
                    {
                        //通知ACC进行换型
                        //根据PartType进行换型，获取相应的参数
                        UISession.CurrentPartType = partType;
                        string msg = String.Empty;
                        UISession.CurrentPartTypeData = accProcess.ChangeModel(partType.PartTypeId, out msg);

                        if (!String.IsNullOrEmpty(msg))
                        {
                            if (UISession.CurrentPartType != null && UISession.CurrentPartType.PartTypeId != 0)
                            {
                                AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("TITLE_ERR_CHANGEOVER"), msg), true);
                            }
                        }
                        else
                        {
                            AddLog(String.Format(LanguageHelper.LoadStringFromResource("MSG_CANGEOVER_COMPLETED"),
                            UISession.CurrentPartType.PartNo), false);

                            try
                            {
                                if (UISession.CurrentPartTypeData.PartTypeDatas != null &&
                                    UISession.CurrentPartTypeData.PartTypeDatas.Count > 0)
                                {
                                    SortedList listInt, listReal, listString;
                                    GetSendPartDataParam(UISession.CurrentPartTypeData.PartTypeDatas, out listInt, out listReal, out listString);
                                    Hashtable htPartTypeDataParam = new Hashtable();
                                    htPartTypeDataParam["N_INT"] = listInt;
                                    htPartTypeDataParam["N_REAL"] = listReal;
                                    htPartTypeDataParam["N_STRING"] = listString;
                                    if (plcProcess != null) plcProcess.WritePartTypeDataACC(htPartTypeDataParam, true);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log4Helper.Error(ex.StackTrace);
                            }

                            if (plcProcess != null) plcProcess.WriteParttypeID(UISession.CurrentPartType.PartTypeId);

                            //换型完成后，填充界面信息
                            CurrentBasicInfo.PartNo = partType.PartNo;
                            CurrentBasicInfo.PartNoDesc = partType.Description;

                            //根据BOM生成当前的条码扫描计数表
                            FillBarcodeListCtrl();

                            //加载缓存的数据计数
                            // LoadDataGridBarcodeCount();
                            //ToDo

                            //完成换型后，则重置一下界面按钮
                            RefreshElementState();
                            SetScanEnable(true);

                            if (UISession.CurrentPartTypeData.ComponentSet != null)
                            {
                                FillLotTrack(UISession.CurrentPartTypeData.ComponentSet);
                            }
                            else
                            {
                                FillLotTrack(new List<ClientLotTrackItem>());
                            }

                            //显示工艺文件列表
                            //Todo
                            List<MESWI> wis = new List<MESWI>();
                            if (UISession.CurrentPartTypeData.Reserved1 != null)
                            {
                                foreach (Object o in UISession.CurrentPartTypeData.Reserved1)
                                {
                                    //wis.Add((MESWI)o);
                                    var data = JsonHelper.ToObject<MESWI>(o.ToString());
                                    wis.Add(data);
                                }
                            }
                            FillWIS(wis);

                            //显示售后、质量问题列表
                            //Todo
                            List<MESIssue> issues = new List<MESIssue>();
                            if (UISession.CurrentPartTypeData.Reserved2 != null)
                            {
                                foreach (Object o in UISession.CurrentPartTypeData.Reserved2)
                                {
                                    //issues.Add((MESIssue)o);
                                    var data = JsonHelper.ToObject<MESIssue>(o.ToString());
                                    issues.Add(data);
                                }
                            }
                            FillIssue(issues);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageDialogWnd.ShowDialog("", "ClientSocket_OnChangeover error:" + ex.Message);
                Log4Helper.Error("ClientSocket_OnChangeover error: ", ex);
            }
        }

        /// <summary>
        /// 整型地址索引样式
        /// </summary>
        public Regex INT_PATTERN = new Regex("INT\\[(\\d+)\\]", RegexOptions.IgnoreCase);
        /// <summary>
        /// 浮点型地址索引样式
        /// </summary>
        public Regex REAL_PATTERN = new Regex("REAL\\[(\\d+)\\]", RegexOptions.IgnoreCase);
        /// <summary>
        /// 字符串型地址索引样式
        /// </summary>
        public Regex STRING_PATTERN = new Regex("STRING\\[(\\d+)\\]", RegexOptions.IgnoreCase);

        /// <summary>
        /// 获取PartTypeData
        /// </summary>
        /// <param name="lsParttypeData"></param>
        /// <param name="listInt"></param>
        /// <param name="listReal"></param>
        /// <param name="listString"></param>
        protected virtual void GetSendPartDataParam(List<ClientParttypeData> lsParttypeData, out SortedList listInt, out SortedList listReal, out SortedList listString)
        {
            listInt = new SortedList();
            listReal = new SortedList();
            listString = new SortedList();
            string address;
            Match match;
            int num;
            Regex regex = null;
            SortedList list = null;
            foreach (ClientParttypeData cfg in lsParttypeData)
            {
                address = cfg.Address;
                if (cfg.ValueType == "PLC_INT")
                {
                    regex = INT_PATTERN;
                    list = listInt;
                }
                else if (cfg.ValueType == "PLC_REAL")
                {
                    regex = REAL_PATTERN;
                    list = listReal;
                }
                else if (cfg.ValueType == "PLC_STRING")
                {
                    regex = STRING_PATTERN;
                    list = listString;
                }
                else
                {
                    continue;
                }
                if (address.ToUpper().IndexOf("INT") != -1)
                {
                    regex = INT_PATTERN;
                    list = listInt;
                }
                else if (address.ToUpper().IndexOf("REAL") != -1)
                {
                    regex = REAL_PATTERN;
                    list = listReal;
                }
                else
                {
                    continue;
                }
                match = regex.Match(address.ToUpper());
                if (match.Success)
                {
                    num = int.Parse(match.Groups[1].Value);
                    if (list.Contains(num))
                    {
                        list[num] = cfg.Value;
                    }
                    else
                    {
                        list.Add(num, cfg.Value);
                    }
                    //if (regex == STRING_PATTERN)
                    //{
                    //    list[num] = cfg.ValueStr;
                    //}
                }
            }
        }

        #endregion

        #region 操作工登录

        /// <summary>
        /// 操作工登录
        /// </summary>
        /// <param name="oper"></param>
        public override void AccSocketServerOperatorChanged(ClientOperator oper)
        {
            UISession.CurrentOperator = oper;
            CurrentBasicInfo.StnOperator = UISession.CurrentOperator.ShowValue;

           

            //操作工发生变化时，重置下按钮
            RefreshElementState();
        }

        #endregion

        #region 物料列表更新

        /// <summary>
        /// 刷新物料
        /// </summary>
        /// <param name="lots"></param>
        public override void FillLotTrack(List<ClientLotTrackItem> lots)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.dgLot.ItemsSource = null;
                this.dgLot.ItemsSource = lots;
            }));
        }

        #endregion

        #region 条码列表更新

        /// <summary>
        /// 初始化条码列表，显示需要显示的条码
        /// </summary>
        private void FillBarcodeListCtrl()
        {
            Dispatcher.Invoke(new Action(() =>
                {
                    if (UISession.CurrentPartTypeData != null && UISession.CurrentPartTypeData.BOMItems != null)
                    {
                        List<BarCodeItem> barcodes = new List<BarCodeItem>();
                        if (ShowComponnets != null && ShowComponnets.Length > 0)
                        {
                            foreach (string idname in ShowComponnets)
                            {
                                // 如果这一站本身就有要显示的码就不再另外增加 -- Sun Qing 
                                if (UISession.CurrentPartTypeData.BOMItems.FirstOrDefault(c => c.IDName == idname) != null)
                                    continue;

                                barcodes.Add(new BarCodeItem()
                                {
                                    ItemPartNo = string.Empty,
                                    IDName = idname,
                                    LeadNo = false,
                                    Qty = 1,
                                    Order = 1,
                                    IsCurrentOP = false
                                });
                            }
                        }

                        List<string> localCodes = LoadDataGridBarcode();//加载本地保存的条码
                        int localIndex = 0;
                        foreach (ClientBomItems bomitem in UISession.CurrentPartTypeData.BOMItems)
                        {
                            int qty;
                            int.TryParse(bomitem.Qty, out qty);
                            for (int i = 1; i <= qty; i++)
                            {
                                barcodes.Add(new BarCodeItem()
                                {
                                    ItemPartNo = bomitem.ItemPartNo,
                                    IDName = bomitem.IDName,
                                    LeadNo = bomitem.LeadNo,
                                    IDPattern = bomitem.IDPattern,
                                    Qty = qty,
                                    Order = i,
                                    IsCurrentOP = UISession.CurrentClient.OP == bomitem.OP,
                                    IDValue = localIndex < localCodes.Count ? localCodes[localIndex] : string.Empty
                                });
                                localIndex++;
                            }
                        }
                        dgBarcode.FillBarCodes(barcodes);
                    }
                }));
        }

        #endregion

        #endregion

        #region PLC通讯

        #region PLC连接
        /// <summary>
        /// 启动PLC连接线程
        /// </summary>
        private void ConnectClientPLC()
        {
            if (UISession.ClientSetting.EnablePLC)
            {
                if (plcProcess == null)
                {
                    plcProcess = new SiemensPlcProcessForSvolt();
                    plcProcess.OnPlcTrigger += new SiemensPlcProcess.PLCEventHandler(PlcProcessTrigger);
                    plcProcess.OnConnected += new SiemensPlcProcess.ConnectedHandler(UpdateDeviceStatus);
                    plcProcess.OnPLCConnected += PLCConnected;

                    if (debugMode == "0")
                    {
                        plcProcess.InitPLC(0, UISession.ClientSetting.PLC_IP, UISession.ClientSetting.PLC_Port, UISession.ClientSetting.PLC_Rack, UISession.ClientSetting.PLC_Slot);
                    }
                    else
                    {
                        plcProcess.InitPLC(1, UISession.ClientSetting.PLC_IP, UISession.ClientSetting.PLC_Port, UISession.ClientSetting.PLC_Rack, UISession.ClientSetting.PLC_Slot);
                    }
                    plcProcess.PlcName = UISession.ClientSetting.PLCDescription;
                    plcProcess.PcSetting = UISession.ClientSetting;

                    plcProcess.CurrentClient = UISession.CurrentClient;
                    plcProcess.CurrentPartType = UISession.CurrentPartType;

                    plcProcess.IsRetryConnect = true;
                    if (!plcProcess.IsConnected)
                    {
                        plcProcess.Start();
                    }
                }
            }
        }

        /// <summary>
        /// 关闭PLC连接
        /// </summary>
        private void CloseClientPLC()
        {
            if (plcProcess != null)
            {
                plcProcess.OnPlcTrigger -= new SiemensPlcProcess.PLCEventHandler(PlcProcessTrigger);
                plcProcess.OnConnected -= new SiemensPlcProcess.ConnectedHandler(UpdateDeviceStatus);
                plcProcess.Stop();
                plcProcess = null;
            }

            if (_ReadPLCThread != null)
            {
                _ReadPLCThread.Abort();
                _ReadPLCThread = null;
            }
        }

        /// <summary>
        /// 连接上PLC之后，还原条码数据（PCClinet重启之后）
        /// </summary>
        public override void PLCConnected()
        {
            try
            {
                if (accSocketServer.IsAccConnected && plcProcess != null && plcProcess.IsConnected && dgBarcode.IsFull)
                    SetDecideBtn(true);
                else
                    SetDecideBtn(false);

                if (accSocketServer.IsAccConnected && plcProcess != null && plcProcess.IsConnected)
                {
                    //连接上PLC以后，开个线程读取OKCount
                    if (_ReadPLCThread == null)
                    {
                        _ReadPLCThread = new Thread(new ThreadStart(ReadPLCThreadProcess));
                        _ReadPLCThread.IsBackground = true;
                        _ReadPLCThread.Name = "Read PLC Thread";
                        _ReadPLCThread.Start();
                    }
                }
                else
                {
                    if (_ReadPLCThread != null)
                    {
                        _ReadPLCThread.Abort();
                        _ReadPLCThread = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Log4Helper.Error(ex.StackTrace);
            }
        }

        Thread _ReadPLCThread = null;

        private void ReadPLCThreadProcess()
        {
//            while (plcProcess != null && plcProcess.IsConnected)
//            {
//                Dispatcher.Invoke(new Action(() =>
//                {
//                    CurrentBasicInfo.OkCount = plcProcess.GetGetOKCount();
//                }));
//
//                Thread.Sleep(3000);
//            }

        }
        #endregion

        #region PLC Load & Unload

        /// <summary>
        /// PLC Load请求
        /// </summary>
        public override void LoadRequestPLC()
        {
            if (plcProcess == null)
                AddLog("PLC 未配置或者断连", true);
            if (UISession.CurrentPartType == null || UISession.CurrentPartType.PartTypeId <= 0)
                AddLog("收到进站PLC请求，等待SCADA换型", false);

            try
            {
                AddLog("收到进站请求信号", false);

                //1.清空条码列表等信息
                dgBarcode.ClearAllBarcodes();
                CurrentBasicInfo.PalletNo = "";
                ResetUnloadDec();

                //2.读取托盘号,显示在界面中
                string trayNo = plcProcess.GetTrayNo();
                AddLog(String.Format(LanguageHelper.LoadStringFromResource("MSG_SCAN_TRAYNO"), trayNo), false);
                CurrentBasicInfo.PalletNo = trayNo;
                if (string.IsNullOrEmpty(trayNo))
                {
                    throw new Exception("未读取到托盘号");
                }
                if (UISession.CurrentPartType == null)
                {
                    throw new Exception("未加载型号");
                }

                /* PLC Load几种情况
                1.不绑定其他条码                 
                2.需要绑定其他条码：
                *                  a) 零件码(GBSN)由ACC生成 ; 
                *                  b) 零件通过PCClinet扫码;
                *                  c) 零件码 来自以上2种情况         
                */

                //2. 发送NextStep，获取要显示的条码
                //accResult.Data存放条码列表;
                //accResult.Message首工位放订单信息



                //如果是首工站，不需要发送NextStep,直接做Load
                if (UISession.ClientSetting.IsFirstOP)
                //if (UISession.CurrentClient.IsFirstOP)
                {
                    //首站直接发送发送托盘号做Load
                    ClientResponse accRes = SendLoadRequest(new List<string>() { trayNo });

                    //////////////模拟数据
                    //accRes.Result = true;
                    //accRes.Message = "WO001,P001,1000";

                    if (accRes.Result == true)
                    {
                        //ACC Load成功
                        AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_SUCCESS"), accRes.Message), false);

                        //模拟Load后ACC返回条码列表
                        List<BarCodeItem> barcodes = JsonHelper.ToObject<List<BarCodeItem>>(accRes.Data.ToString());

                        //////////////模拟数据
                        //List<BarCodeItem> barcodes = new List<BarCodeItem>() { 
                        //    new BarCodeItem(){
                        //        IDName="PACK",
                        //        IDValue="PACK20200414135753"
                        //    },
                        //    new BarCodeItem(){
                        //        IDName="GBSN",
                        //        IDValue="GBSN20200414135753"
                        //    }
                        //};

                        CurrentBasicInfo.GbSn = string.Empty;
                        foreach (BarCodeItem bi in barcodes)
                        {
                            if ("GBSN".Equals(bi.IDName.ToUpper()))
                                CurrentBasicInfo.GbSn = bi.IDValue;
                            dgBarcode.FillBarcodeValueByName(bi);
                        }

                        // 首工序需要把写给PLC
                        if (plcProcess != null)
                        {
                            plcProcess.LoadSuccessfully();
                            if (dgBarcode.MainItem != null)
                            {
                                plcProcess.WriteInterSNToPlc(dgBarcode.MainItem.IDValue);
                                AddLog(string.Format("写入内部码:{0}", dgBarcode.MainItem.IDValue), false);
                            }
                            if (!string.IsNullOrEmpty(accRes.Message))
                            {
                                var wo = JsonHelper.ToObject<ClientWorkOrder>(accRes.Message);
                                if (wo != null)
                                {
                                    UInt16 qty;
                                    UInt16.TryParse(wo.PlanQuantity, out qty);
                                    plcProcess.WritePartNoToPlc(wo.PartNo);    // 写入产品型号
                                    AddLog(string.Format("写入产品型号:{0}", wo.PartNo), false);
                                    plcProcess.WritePlanCountToPlc(wo.PlanQuantity); // 写入订单数量
                                    AddLog(string.Format("写入订单数量:{0}", wo.PlanQuantity), false);

                                    CurrentBasicInfo.OrderNo = wo.PONO;
                                    CurrentBasicInfo.OrderQty = qty;
                                }
                            }
                        }

                        //将条码保存在本地
                        clientSqlLite.DeleteBarcodeAll();
                        foreach (BarCodeItem bi in dgBarcode.Barcodes)
                        {
                            clientSqlLite.InsertBarcode2(bi.IDValue, "OK");//条码保存到本地
                            bi.Status = BarcodeStatus.OK;
                        }
                    }
                    else
                    {
                        //ACC Load没有成功，显示错误信息
                        if (plcProcess != null)
                        {
                            plcProcess.LoadFailed();
                        }

                        AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_FAILD"), accRes.Message), true);
                        SetDecideBtn(false);
                    }
                }
                else//中间站需要发送NextStep
                {
                    ClientResponse accResult = accProcess.NextStep(new List<string>() { trayNo }, UISession.CurrentPartType.PartTypeId);
                    if (accResult.Result == false)
                    {
                        throw new Exception("NextStep Err:" + accResult.Message);
                    }
                    else
                    {
                        if (accResult.Data != null && !string.IsNullOrEmpty(accResult.Data.ToString()))
                        {
                            List<BarCodeItem> barcodes = JsonHelper.ToObject<List<BarCodeItem>>(accResult.Data.ToString());

                            CurrentBasicInfo.GbSn = string.Empty;
                            foreach (BarCodeItem bi in barcodes)
                            {
                                if ("GBSN".Equals(bi.IDName.ToUpper()))
                                    CurrentBasicInfo.GbSn = bi.IDValue;
                                dgBarcode.FillBarcodeValueByName(bi);
                            }
                        }

                        if (!string.IsNullOrEmpty(accResult.Message))
                            AddLog(accResult.Message, false);
                    }

                    //3. 如果条码已满，直接Load
                    if (dgBarcode.IsFull)
                    {
                        ProcessLoad();
                    }
                    else
                    {
                        SetScanEnable(true);
                    }
                }

                //通过Next Step说明可以在当前工位生产
                //  plcProcess.LoadSuccessfully();

            }
            catch (Exception ex)
            {
                AddLog("Load 异常:" + ex.Message, true);
                Log4Helper.Error("ProcessLoadPLC Err:" + ex.ToString());
                plcProcess.LoadFailed();
            }
        }

        /// <summary>
        /// PLC Unload请求
        /// </summary>
        public override void UnloadRequestPLC()
        {
            if (plcProcess != null)
            {
                AddLog("收到出站请求信号", false);

                if (ProcessUnload(unloadResult, unloadNGData))
                {
                    plcProcess.UnloadSuccessfully(unloadResult);
                }
                else
                {
                    plcProcess.UnloadFailed();
                }
            }
        }

        #endregion

        #region 三大件叫料
        public override void MaterialInRequestPLC(int portNo)
        {
            AddLog(string.Format("收到上料{0}信号", portNo), false);
            string fixtureNum = plcProcess.GetFixtureNum();
            ClientResponse res = accProcess.MaterialIn(fixtureNum, portNo, false);
            if (res.Result)
            {
                // port口为1,2,3,4、对应的bit位分别为0,2,4,6 
                int bSite = (Convert.ToInt32(portNo) - 1) * 2;
                plcProcess.MaterialInResult(bSite);
                AddLog(string.Format("上料{0}信号已通知MES", portNo), false);
            }
        }

        public override void MaterialOutRequestPLC(int portNo)
        {
            AddLog(string.Format("收到下料{0}信号", portNo), false);
            string fixtureNum = plcProcess.GetFixtureNum();
            ClientResponse res = accProcess.MaterialOut(fixtureNum, portNo);
            if (res.Result)
            {
                // port口为1,2,3,4、对应的bit位分别为1,3,5,7 
                int bSite = (Convert.ToInt32(portNo) - 1) * 2 + 1;
                plcProcess.MaterialOutResult(bSite);
                AddLog(string.Format("下料{0}信号已通知MES", portNo), false);
            }

        }

        public override void MaterialCoreInRequestPLC()
        {
            AddLog(string.Format("收到叫料信号"), false);
            ClientResponse res = accProcess.MaterialIn("", 1, true);
            if (res.Result)
            {
                int bSite = 0;
                plcProcess.MaterialCoreInResult(bSite);
                AddLog(string.Format("叫料信号已通知MES"), false);
            }
        }

        #endregion

        #endregion

        #region 扫码
        /// <summary>
        /// 点击扫描图标按钮，相当于按回车
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImageButton_Click(object sender, RoutedEventArgs e)
        {
            HandleBarcode(this.txtScan.Text);
        }

        //Thread ThreadHandleBarcode;
        /// <summary>
        /// 设置读码Handle
        /// </summary>
        //private void SetBarcodeHandle()
        //{
        //    _isRun = false;
        //    if (ThreadHandleBarcode != null)
        //    {
        //        try
        //        {
        //            ThreadHandleBarcode.Abort();
        //        }
        //        catch { }
        //        finally { ThreadHandleBarcode = null; }
        //    }

        //    _isRun = true;
        //    ThreadHandleBarcode = new Thread(new ThreadStart(HandleBarcodeMethod));
        //    ThreadHandleBarcode.IsBackground = true;
        //    ThreadHandleBarcode.Start();
        //}

        /// <summary>
        /// 扫码事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtScan_KeyDown(object sender, KeyEventArgs e)
        {
            Thread.Sleep(1);

            if (e.Key == Key.Enter)
            {
                Dispatcher.Invoke(new Action(() =>
                {
                    string barcode = txtScan.Text.Trim();//.ToUpper();

                    if (string.IsNullOrEmpty(barcode))
                    {
                        return;
                    }
                    else
                    {
                        //_scanBarcode = barcode;
                        //显示扫描信息
                        AddLog(String.Format(
                            LanguageHelper.LoadStringFromResource("MSG_SCAN_BARCODE"),
                            barcode) + " at time : " + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), false);
                        HandleBarcode(barcode);
                    }
                }));
            }
        }

        /// <summary>
        /// 处理条码
        /// </summary>
        //private void HandleBarcodeMethod()
        //{
        //    while (_isRun)
        //    {
        //        Thread.Sleep(10);
        //        Dispatcher.Invoke(new Action(() =>
        //        {
        //            HandleBarcode();
        //        }));
        //    }
        //}

        /// <summary>
        /// 条码处理Handle
        /// </summary>
        private void HandleBarcode(string barcode)
        {
            //显示扫描信息
            AddLog(String.Format(LanguageHelper.LoadStringFromResource("MSG_SCAN_BARCODE"), barcode), false);
            bool bRet = true;
            try
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    this.Cursor = Cursors.Wait;
                }));

                //扫描的码有2种情况:唯一码，批次码               
                //通过正则验证:唯一码  
                // 都有 ACC来判断 
                ProcessUniqueCode(barcode);
                //if (dgBarcode.MatchBarcode(barcode))
                //{
                //    ProcessUniqueCode(barcode);     
                //}
                //else //否则视为物料批次码
                //{
                //    ProcessMaterialCode(barcode);
                //}  
            }
            catch (Exception ex)
            {
                Log4Helper.Error("Scan Barcode Error: ", ex);
                AddLog(ex.Message, true);
                bRet = false;
            }
            finally
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    // 扫描检查失败，将条码留在扫描框中
                    if (bRet) txtScan.Text = String.Empty;
                    txtScan.Focus();
                    txtScan.SelectAll();
                    this.Cursor = Cursors.Arrow;
                }));
            }
        }

        private void ProcessUniqueCode(string barcode)
        {
            //AddLog("扫描唯一码:" + barcode, false);

            //检查该条码是否已经扫过，如果扫过则不做处理
            if (IsBarcodeRepeat(barcode))
            {
                throw new Exception(string.Format("{0}:{1}",
                    LanguageHelper.LoadStringFromResource("MSG_ERR_BARCODE_DUPLICATED"),
                    txtScan.Text));
            }

            string errMessage;
            if (DoPreLoad(barcode, out errMessage))
            {
                if (IsAllBarcodeEmpty())
                {
                    FillMainItemBarcode(barcode);
                }
                else
                {
                    FillItemBarcode(barcode);
                }

                //此版本没有Load按钮，条码满后自动Load
                if (dgBarcode.IsFull)
                {
                    new Thread(delegate()
                    {
                        Thread.Sleep(1000);
                        //Load成功之后，对于非PLC客户端，根据AutoUnload配置做自动Unload
                        if (ProcessLoad() && plcProcess == null
                                          && !IsManualResult) //add by Han ,不需要输入OK和NOK的才需要直接触发Unload
                        {
                            ProcessUnload(1);
                        }
                    }).Start();
                }
            }
            else
            {
                plcProcess.LoadByPass();
                throw new Exception(string.Format("条码{0}检查失败:{1}", barcode, errMessage));
            }
        }

        private void FillItemBarcode(string barcode)
        {
            string msg = "";
            if (!dgBarcode.OnReadBarcode(barcode, out msg))
            {
                throw new Exception(msg);
            }
        }

        private bool DoPreLoad(string barcode, out string errMessage)
        {
            errMessage = "";

            List<string> barcodes = new List<string> { };
            if (dgBarcode.MainItem != null && !string.IsNullOrEmpty(dgBarcode.MainItem.IDValue))
            {
                barcodes.Add(dgBarcode.MainItem.IDValue);
            }
            barcodes.Add(barcode);

            var accResult = accProcess.PreLoad(barcodes, string.Empty, UISession.CurrentPartType.PartTypeId);

            // dgBarcode.FillBarCodes(dgBarcode.Barcodes);
            if (accResult.Result == false)
            {
                //因为后台PreloadOK没有给Code作为区分，所以这边不好区分是因为路由失败还是其他的问题导致的NextStepNOK，只能通过描述来判断。
                if (accResult.Message.IndexOf("工件应在工位", StringComparison.Ordinal) != -1)
                {
                    errMessage = accResult.Message;
                    return false;
                }

                throw new Exception(string.IsNullOrEmpty(accResult.Message) ? "条码未通过校验" : accResult.Message);
            }

            if (!string.IsNullOrEmpty(accResult.Message))
            {
                AddLog(accResult.Message, false);
            }

            return true;
        }

        private void FillMainItemBarcode(string barcode)
        {
            if (dgBarcode.MainItem != null && string.IsNullOrEmpty(dgBarcode.MainItem.IDValue))
            {
                dgBarcode.MainItem.IDValue = barcode;
                dgBarcode.MainItem.Status = BarcodeStatus.OK;
            }
        }

        private bool IsAllBarcodeEmpty()
        {
            for (var i = 0; i < dgBarcode.Barcodes.Count; i++)
            {
                if (dgBarcode.Barcodes[i].IDValue != "")
                    return false;
            }

            return true;
        }

        /// <summary>
        /// 处理唯一码
        /// </summary>
        /// <param name="barcode"></param>
        private void ProcessUniqueCode_Old(string barcode)
        {
            //AddLog("扫描唯一码:" + barcode, false);

            //检查该条码是否已经扫过，如果扫过则不做处理
            if (IsBarcodeRepeat(barcode))
            {
                throw new Exception(string.Format("{0}:{1}",
                    LanguageHelper.LoadStringFromResource("MSG_ERR_BARCODE_DUPLICATED"),
                    txtScan.Text));
            }

            string msg;
            ClientResponse accResult;

            //Preload，校验条码是否有效
            //if (UISession.ClientSetting.NeedPreLoad)
            {
                //Preload必须要有主条码
                //if (dgBarcode.MainItem == null || string.IsNullOrEmpty(dgBarcode.MainItem.IDValue))
                //{
                //    throw new Exception("缺失主条码,无法校验零件是否可用");
                //}

                //零件码的PreLoad校验是否可与当前主条码绑定
                //主条码的PreLoad校验路由
                List<string> barcodes = new List<string> { };
                if (dgBarcode.MainItem != null && !string.IsNullOrEmpty(dgBarcode.MainItem.IDValue))
                {
                    barcodes.Add(dgBarcode.MainItem.IDValue);
                }
                barcodes.Add(barcode);

                accResult = accProcess.PreLoad(barcodes, string.Empty, UISession.CurrentPartType.PartTypeId);

                // dgBarcode.FillBarCodes(dgBarcode.Barcodes);
                if (accResult.Result == false)
                {
                    throw new Exception(string.IsNullOrEmpty(accResult.Message) ? "条码未通过校验" : accResult.Message);
                }

                if (accResult.Data != null && !string.IsNullOrEmpty(accResult.Data.ToString()))
                {
                    List<BarCodeItem> barcodeItems = JsonHelper.ToObject<List<BarCodeItem>>(accResult.Data.ToString());

                    if (barcodeItems != null && barcodeItems.Count > 0)
                    {
                        CurrentBasicInfo.GbSn = string.Empty;
                        foreach (BarCodeItem bi in barcodeItems)
                        {
                            if ("GBSN".Equals(bi.IDName.ToUpper()))
                                CurrentBasicInfo.GbSn = bi.IDValue;
                            dgBarcode.FillBarcodeValueByName(bi);
                        }
                    }
                }

                if (!string.IsNullOrEmpty(accResult.Message))
                {
                    AddLog(accResult.Message, false);
                    return;
                }

                if (!dgBarcode.OnReadBarcode(barcode, out msg))
                {
                    throw new Exception(msg);
                }
            }

            //此版本没有Load按钮，条码满后自动Load
            if (dgBarcode.IsFull)
            {
                //Load成功之后，对于非PLC客户端，根据AutoUnload配置做自动Unload
                if (ProcessLoad() && plcProcess == null)
                {
                    ProcessUnload(1);
                }
            }
        }

        /// <summary>
        /// 处理物料批次码
        /// </summary>
        /// <param name="barcode"></param>
        private void ProcessMaterialCode(string barcode)
        {
            AddLog("扫描物料批次码:" + barcode, false);

            ClientResponse accResult = accProcess.ProcessMaterialCode(barcode);
            AddLog(accResult.Message, !accResult.Result);

            if (accResult.Data != null && !string.IsNullOrEmpty(accResult.Data.ToString()))
            {
                List<ClientLotTrackItem> data = JsonHelper.ToObject<List<ClientLotTrackItem>>(accResult.Data.ToString());
                FillLotTrack(data);
            }
        }


        /// <summary>
        /// 检验条码是否已经扫描重复
        /// </summary>
        /// <param name="barcode"></param>
        /// <returns></returns>
        private bool IsBarcodeRepeat(string barcode)
        {
            foreach (var bi in dgBarcode.Barcodes)
            {
                if (!string.IsNullOrEmpty(bi.IDValue) && bi.IDValue.Equals(barcode))
                {
                    return true;
                }
            }
            return false;
        }
        #endregion

        #region Load & Unload

        /// <summary>
        /// 清空上次选择的Unload结果
        /// </summary>
        private void ResetUnloadDec()
        {
            unloadResult = 1;
            unloadNGData = null;
        }

        /// <summary>
        /// 执行Load
        /// </summary>
        private bool ProcessLoad()
        {
            try
            {
                List<string> barcodes = new List<string>();
                clientSqlLite.DeleteBarcodeAll();
                foreach (BarCodeItem bi in dgBarcode.Barcodes)
                {
                    clientSqlLite.InsertBarcode2(bi.IDValue, "OK");//条码保存到本地
                    bi.Status = BarcodeStatus.OK;
                    if (bi.IsCurrentOP || bi.LeadNo)
                    {
                        barcodes.Add(bi.IDValue);
                    }
                }

                Thread.Sleep(10);

                ClientResponse accResult = accProcess.Load(barcodes, UISession.CurrentPartType.PartTypeId);
                if (accResult.Result == true)
                {
                    if (plcProcess != null)
                    {
                        plcProcess.LoadSuccessfully();
                        plcProcess.WriteBarcodes(barcodes);
                    }
                    
                    AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_SUCCESS"), string.Empty), false);
                    SetDecideBtn(true);
                    return true;
                }
                else
                {
                    if (plcProcess != null)
                    {
                        plcProcess.LoadFailed();
                    }

                    AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_FAILD"), accResult.Message), true);
                    SetDecideBtn(false);
                    return false;
                }
            }
            catch (Exception ex)
            {
                if (plcProcess != null) plcProcess.LoadFailed();
                AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("MSG_ACC_LOAD_FAILD"), ex.Message), true);
                SetDecideBtn(false);
                return false;
            }
        }

        /// <summary>
        /// 执行Unload
        /// </summary>
        /// <returns></returns>
        private bool ProcessUnload(int statusBit, UnloadVariable unloadData = null)
        {
            try
            {
                Log4Helper.Debug("ProcessUnload start");
                Log4Helper.Trace("ProcessUnload start");
                int failureBits = 0;
                List<ClientProcData> lstProcessData = UISession.CurrentPartTypeData != null ? UISession.CurrentPartTypeData.ProcDatas.ToList() : null;

                Log4Helper.Debug(string.Format("lstProcessData|{0} ", lstProcessData != null));
                Log4Helper.Trace("try to get into  GetStatusBits");
                if (lstProcessData != null && lstProcessData.Count > 0 && plcProcess != null 
                    && !IsManualResult)
                {
                    plcProcess.GetProcData(ref lstProcessData);
                    Log4Helper.Debug("try to get into  GetStatusBits");
                    Log4Helper.Trace("try to get into  GetStatusBits");
                    plcProcess.GetStatusBits(out statusBit, out failureBits);
                }

                List<string> barcodes = new List<string>();
                foreach (BarCodeItem bi in dgBarcode.Barcodes)
                {
                    if (bi.IsCurrentOP || bi.LeadNo)
                    {
                        barcodes.Add(bi.IDValue);
                    }
                }
                ClientResponse unloadResult = SendUnloadRequest(barcodes, lstProcessData, unloadData, statusBit, failureBits);

                if (!unloadResult.Result)
                {
                    AddLog(String.Format("{0}:{1}", LanguageHelper.LoadStringFromResource("MSG_ACC_UNLOAD_FAILD"), unloadResult.Message), true);
                    return false;
                }
                AddLog(LanguageHelper.LoadStringFromResource("MSG_ACC_UNLOAD_SUCCESS"), false);

                if (unloadResult.Data != null)
                {
                    List<ClientLotTrackItem> data = JsonHelper.ToObject<List<ClientLotTrackItem>>(unloadResult.Data.ToString());
                    FillLotTrack(data);
                }

                //重置界面元素
                ResetCycle();

                //Unload结束之后，如果是PLC工位，则不能扫码
                // 可能要扫物料码
                //SetScanEnable(plcProcess == null);                   
                return true;
            }
            catch (Exception ex)
            {
                MessageDialogWnd.ShowDialog("", "ACC Unload Error:" + ex.Message);
                Log4Helper.Error("ACC Unload Error: ", ex);
                return false;
            }
        }

        #endregion

        #region SOP
        //FtpHelper ftp = null;
        //填充工艺文件
        public override void FillWIS(List<MESWI> wis)
        {
            //从远程FTP加载工艺文件列表
            AddSopVideoList(wis);
        }

        private void LoadHelp()
        {
            //获取操作手册目录
            string helpFullName = System.AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["HelpFolder"].ToString();
            //本地目录存在则加载
            if (Directory.Exists(helpFullName))
            {
                DirectoryInfo TheFolder = new DirectoryInfo(helpFullName);
                foreach (FileInfo NextFile in TheFolder.GetFiles())
                {
                    if (IsVideoType(NextFile.Name) || IsImageType(NextFile.Name) || IsPdfType(NextFile.Name))
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            CheckBox chk = new CheckBox();
                            chk.Margin = new Thickness(5);
                            chk.FontSize = 28;
                            chk.Tag = NextFile.Name;
                            chk.Content = NextFile.Name;

                            chk.Checked += Chk_HelpChecked;
                            chk.Unchecked += Chk_Unchecked;
                            pnlSopVideoList.Children.Add(chk);
                        }));
                    }
                }
            }
        }

        void Chk_HelpChecked(object sender, RoutedEventArgs e)
        {
            var chk = sender as CheckBox;

            if (chk != null)
            {
                foreach (CheckBox child in pnlSopVideoList.Children)
                {
                    if ((bool)child.IsChecked && child.Tag != chk.Tag)
                        child.IsChecked = false;
                }

                ResetSopPlayer(ConfigurationManager.AppSettings["HelpFolder"].ToString(), chk);
            }
        }

        void AddSopVideoList(List<MESWI> wis)
        {
            //MESWI temp = new MESWI();
            //temp.wi_filename = "E1B5015D175877EA557E3166C10AB57C.mp4";
            //temp.wi_filepath = "ftp://127.0.0.1";
            //wis.Add(temp);

            //MESWI temp1 = new MESWI();
            //temp1.wi_filename = "How to use MC 3000-20120607 [Compatibility Mode].pdf";
            //temp1.wi_filepath = "ftp://127.0.0.1";
            //wis.Add(temp1);

            //MESWI temp2 = new MESWI();
            //temp2.wi_filename = "微信截图_20181120142244.png";
            //temp2.wi_filepath = "ftp://127.0.0.1";
            //wis.Add(temp2);
            new Thread(new ThreadStart(delegate()
            {
                Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (pnlSopVideoList != null && pnlSopVideoList.Children != null)
                    {
                        pnlSopVideoList.Children.Clear();
                        //LoadHelp();
                    }
                }));

                //下载到本地目录
                string SopFolderFullName = System.AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["SopFolder"].ToString();
                //本地目录不存在则创建
                if (!Directory.Exists(SopFolderFullName))
                {
                    Directory.CreateDirectory(SopFolderFullName);
                }

                //if (wis.Count == 0)//网络路径没搜索到文件，就加载本地文件
                //{
                //    LoadLocalFiles(SopFolderFullName);
                //    return;
                //}

                //string ftpServerIP = "127.0.0.1";
                //string mask = "*.*";
                string uid = ConfigurationManager.AppSettings["FTPUser"].ToString();
                string pwd = ConfigurationManager.AppSettings["FTPPwd"].ToString();
                //ftp = new FtpHelper(ftpServerIP, "", uid, pwd);
                //string[] fileNames = ftp.GetFileList(mask);


                foreach (MESWI wi in wis)
                {
                    if (IsVideoType(wi.wi_filename) || IsImageType(wi.wi_filename) || IsPdfType(wi.wi_filename))
                    {
                        //CheckBox chk = null;
                        //Dispatcher.BeginInvoke(new Action(() =>
                        //{
                        //    chk = new CheckBox();
                        //    chk.Margin = new Thickness(5);
                        //    chk.FontSize = 24;
                        //    chk.Tag = wi.wi_filename;
                        //    chk.Content = wi.wi_filename;

                        //    chk.Checked += Chk_Checked;
                        //    chk.Unchecked += Chk_Unchecked;
                        //    pnlSopVideoList.Children.Add(chk);
                        //}));

                        FtpHelper ftp = new FtpHelper(uid, pwd);
                        //获取ftp上文件最后更新时间
                        DateTime dtFtpLast = ftp.GetFileModifyDateTime(wi.wi_filepath + "/" + wi.wi_filename);
                        //获取本地文件最后更新时间
                        DateTime dtLocLast = DateTime.MinValue;
                        bool isExist = File.Exists(SopFolderFullName + "\\" + wi.wi_filename);
                        if (isExist)
                        {
                            FileInfo file = new FileInfo(SopFolderFullName + "\\" + wi.wi_filename);
                            dtLocLast = file.LastWriteTime;
                            if (dtFtpLast > dtLocLast) file.Delete();
                        }
                        if (dtFtpLast > dtLocLast)
                        {
                            //Dispatcher.BeginInvoke(new Action(() =>
                            //{
                            //    chk.IsEnabled = false;
                            //    chk.Content = "..." + chk.Content.ToString();
                            //}));
                            new Thread(new ThreadStart(delegate()
                            {
                                ftp.Download(SopFolderFullName, wi.wi_filename, wi.wi_filepath);
                                //Dispatcher.BeginInvoke(new Action(() =>
                                //{
                                //    chk.Content = chk.Content.ToString().Replace("...", "");
                                //    chk.IsEnabled = true;
                                //}));
                            })).Start();
                        }
                    }
                }

                LoadLocalFiles(wis, SopFolderFullName);
                //Dispatcher.BeginInvoke(new Action(() =>
                //{
                //    if (pnlSopVideoList.Children.Count == 0) LoadLocalFiles(SopFolderFullName);
                //}));
            })).Start();

        }

        void LoadLocalFiles(List<MESWI> wis, string SopFolderFullName)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                pnlSopVideoList.Children.Clear();
            }));
            DirectoryInfo TheFolder = new DirectoryInfo(SopFolderFullName);
            foreach (FileInfo NextFile in TheFolder.GetFiles())
            {
                if (wis != null && wis.FirstOrDefault(c => c.wi_filename == NextFile.Name) == null) continue;

                if (IsVideoType(NextFile.Name) || IsImageType(NextFile.Name) || IsPdfType(NextFile.Name))
                {
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        CheckBox chk = new CheckBox();
                        chk.Margin = new Thickness(5);
                        chk.FontSize = 28;
                        chk.Tag = NextFile.Name;
                        chk.Content = NextFile.Name;

                        chk.Checked += Chk_Checked;
                        chk.Unchecked += Chk_Unchecked;
                        pnlSopVideoList.Children.Add(chk);
                    }));
                }
            }
        }

        void ResetSopPlayer(string pathDir, CheckBox chk)
        {
//            try
//            {
//                sopMediaPlayer.Ctlcontrols.stop();
//
//                string path = @".\" + pathDir + "\\" + chk.Tag.ToString();
//                string fname = chk.Tag.ToString();
//
//                if (!System.IO.File.Exists(path))
//                {
//                    sopMediaPlayer.URL = "";
//                    MessageDialogWnd.ShowDialog("操作指导", "本地无该文件");
//                    //if (MessageDialogWnd.ShowDialog("操作指导", "本地无该文件，是否从服务器端下载？"))
//                    //{
//                    //    new Thread(new ThreadStart(delegate()
//                    //    {
//                    //        Dispatcher.BeginInvoke(new Action(() =>
//                    //        {
//                    //            chk.IsEnabled = false;
//                    //            chk.Content = "..." + chk.Content.ToString();
//                    //        }));
//                    //        ftp.Download(System.AppDomain.CurrentDomain.BaseDirectory + pathDir, fname);
//                    //        Dispatcher.BeginInvoke(new Action(() =>
//                    //        {
//                    //            chk.Content = chk.Content.ToString().Replace("...", "");
//                    //            chk.IsEnabled = true;
//                    //        }));
//                    //    })).Start();
//                    //}
//                    chk.IsChecked = false;
//                    return;
//                }
//
//                if (IsVideoType(path))
//                {
//                    sopMediaPlayer.URL = path;
//                    sopMediaPlayer.settings.volume = 100;
//                    sopMediaPlayer.settings.setMode("loop", true);//设置循环播放
//                    sopMediaPlayer.Ctlcontrols.play();
//
//                    svMediaPlayer.Visibility = System.Windows.Visibility.Visible;
//                    svImage.Visibility = System.Windows.Visibility.Hidden;
//                    //svPdfViewer.Visibility = System.Windows.Visibility.Hidden;
//                    moonPdfPanel.Visibility = System.Windows.Visibility.Hidden;
//                }
//                else if (IsPdfType(path))
//                {
//                    //Dispatcher.Invoke(new Action(() =>
//                    //{
//                    //this.sopPdfViewer.LoadFromFile(path);
//                    //}));
//                    svMediaPlayer.Visibility = System.Windows.Visibility.Hidden;
//                    svImage.Visibility = System.Windows.Visibility.Hidden;
//                    //svPdfViewer.Visibility = System.Windows.Visibility.Visible;
//                    moonPdfPanel.Visibility = System.Windows.Visibility.Visible;
//                    Dispatcher.BeginInvoke(new Action(() =>
//                    {
//                        //this.sopPdfViewer.LoadFromFile(path);
//                        //Thread.Sleep(3000);
//                        this.moonPdfPanel.OpenFile(path);
//                    }));
//                }
//                else if (IsImageType(path))
//                {
//                    if (System.IO.File.Exists(AppDomain.CurrentDomain.BaseDirectory + path))
//                    {
//                        Uri uri = new Uri(AppDomain.CurrentDomain.BaseDirectory + path, UriKind.RelativeOrAbsolute);
//
//                        imgSop.Source = new System.Windows.Media.Imaging.BitmapImage(uri);
//                    }
//                    else
//                        imgSop.Source = null;
//
//                    svMediaPlayer.Visibility = System.Windows.Visibility.Hidden;
//                    svImage.Visibility = System.Windows.Visibility.Visible;
//                    //svPdfViewer.Visibility = System.Windows.Visibility.Hidden;
//                    moonPdfPanel.Visibility = System.Windows.Visibility.Hidden;
//                }
//                else
//                {
//                    AddLog("SOP文件格式不支持", true);
//                }
//            }
//            catch (Exception ex)
//            {
//                AddLog("SOP显示失败:" + ex.Message, true);
//            }
        }

        private string ImageFileType = "BMP,JPG,JPEG,PNG,GIF";
        private string VideoFileType = "AVI,MP4,WMA,RMVB,3GP";
        private string PDFFileType = "PDF";
        bool IsVideoType(string path)
        {
            string fileType = path.Substring(path.LastIndexOf(".") + 1);
            if (VideoFileType.Contains(fileType.ToUpper()))
                return true;

            return false;
        }
        bool IsImageType(string path)
        {
            string fileType = path.Substring(path.LastIndexOf(".") + 1);
            if (ImageFileType.Contains(fileType.ToUpper()))
                return true;

            return false;
        }
        bool IsPdfType(string path)
        {
            string fileType = path.Substring(path.LastIndexOf(".") + 1);
            if (PDFFileType.Contains(fileType.ToUpper()))
                return true;

            return false;
        }

        void Chk_Checked(object sender, RoutedEventArgs e)
        {
            var chk = sender as CheckBox;

            if (chk != null)
            {
                foreach (CheckBox child in pnlSopVideoList.Children)
                {
                    if ((bool)child.IsChecked && child.Tag != chk.Tag)
                        child.IsChecked = false;
                }

                ResetSopPlayer(ConfigurationManager.AppSettings["SopFolder"].ToString(), chk);
            }
        }

        void Chk_Unchecked(object sender, RoutedEventArgs e)
        {
            var chk = sender as CheckBox;
            if (chk != null)
            {
                string fileName = chk.Tag.ToString();
//                if (IsVideoType(fileName))
//                {
//                    sopMediaPlayer.Ctlcontrols.stop();
//                }
//                svMediaPlayer.Visibility = System.Windows.Visibility.Hidden;
                svImage.Visibility = System.Windows.Visibility.Hidden;
                svPdfViewer.Visibility = System.Windows.Visibility.Hidden;
            }
        }
        #endregion

        #region Issue

        public override void FillIssue(List<MESIssue> issues)
        {
            //MESIssue t1 = new MESIssue();
            //t1.op_code = "L1M03030";
            //t1.op_name = "预埋钢扎带";
            //t1.cell_code = "L1M13031";
            //t1.cell_name = "预埋钢扎带";
            //t1.issue_des = "质量问题";
            //issues.Add(t1);
            Dispatcher.BeginInvoke(new Action(() =>
            {
                this.gridAfterSale.ItemsSource = null;
                this.gridAfterSale.ItemsSource = issues;
            }));
        }

        #endregion

        #region 国标码
        /// <summary>
        /// 把国标码写给PLC
        /// </summary>
        /// <param name="issues"></param>
        public override void ReceivedGBSN(string gbsn)
        {
            Dispatcher.BeginInvoke(new Action(() =>
            {
                CurrentBasicInfo.GbSn = gbsn;

                dgBarcode.FillBarcodeValueByName("GBSN", gbsn);
            }));
        }
        #endregion

        private void InitSettings()
        {
            if (UISession.CurrentClient.StnClientCfg == null) return;
            Dispatcher.BeginInvoke(new Action(() =>
            {
                //this.TabItem2.IsSelected = true;
                //    UISession.CurrentClient.StnClientCfg = new List<ACCStnClientConfig>() { 
                //    new ACCStnClientConfig(){
                //        GroupName="客户端配置",
                //        GroupItem="是否首工位",
                //        GroupType=3,
                //        ItemValue="False"
                //    },
                //    new ACCStnClientConfig(){
                //        GroupName="客户端配置",
                //        GroupItem="test",
                //        GroupType=3,
                //        ItemValue="True"
                //    },
                //    new ACCStnClientConfig(){
                //        GroupName="PLC配置",
                //        GroupItem="test",
                //        GroupType=0,
                //        ItemValue="aaaaaaaaa"
                //    }
                //};

                var groups = (from p in UISession.CurrentClient.StnClientCfg group p by p.GroupName into g select new { g.Key }).ToList();

                foreach (var item in groups)
                {
                    TabItem tabItem = new TabItem();
                    tabItem.Header = item.Key;

                    SettingListControl tabContent = new SettingListControl();
                    tabContent.FillSettings(UISession.CurrentClient.StnClientCfg.Where(p => item.Key.Equals(p.GroupName)).ToList());
                    tabItem.Content = tabContent;
                    tabSetting.Items.Add(tabItem);
                }

                //Grid grid = new Grid();
                //grid.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#f7f7f7"));
            }));
        }

        private void btnSaveSetting_Click(object sender, RoutedEventArgs e)
        {
            if (UISession.CurrentClient.StnClientCfg != null)
            {
                ClientResponse result = accProcess.SaveClientCfg(UISession.CurrentClient.StnClientCfg);
                if (result.Result)//保存成功
                {
                    MessageBox.Show(LanguageHelper.LoadStringFromResource("MSG_STORE_SUCCESS"));
                }
                else//保存失败
                {
                    MessageBox.Show(LanguageHelper.LoadStringFromResource("MSG_STORE_FAIL") + "：" + result.Message);
                }
            }
        }

        protected bool PalletStatus = false;

        /// <summary>
        /// add by han receive the pallet arrival or leave
        /// </summary>
        /// <param name="isOn"></param>
        public override void PalletRequestPLC(bool isOn)
        {
            PalletStatus = isOn;
            if (isOn)
            {
                if (UISession.CurrentPartType == null || UISession.CurrentPartType.PartTypeId <= 0)
                {
                    AddLog("设备就绪，等待ACC换型", false);
                }
                else
                {
                    AddLog("设备就绪，请扫描条码", false);
                }
            }
            SetScanEnable(isOn);
        }

        public override void FaultRequestPLC()
        {
            int code;
            string msg;
            plcProcess.GetFaultMessage(out code, out msg);
            AddLog(string.Format("PLC报错：[{0}]{1}" , code,  msg), true);
        }

        public override void TipRequestPLC()
        {
            string msg;
            bool alarm;
            plcProcess.GetTipMessage(out msg,out alarm);
            AddLog(msg, alarm);
        }
    }
}
